﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using Microsoft.Expression.Interactivity.Core;
using QDP.Platform.ObjService;
using QDP.Platform.Services;
namespace QDP.Platform.Silverlight.Controls
{
    [TemplatePart(Name = KEY_PART_LeftThumb, Type = typeof(Border))]
    [TemplatePart(Name = KEY_PART_RightThumb, Type = typeof(Border))]
    [TemplatePart(Name = KEY_PART_ExpandController, Type = typeof(ToggleButton))]
    [TemplatePart(Name = KEY_PART_ExpandedAll, Type = typeof(Button))]
    [TemplatePart(Name = KEY_PART_CollapseAll, Type = typeof(Button))]
    [TemplatePart(Name = KEY_PART_CustomRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_WidgetArea, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_BotomRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_RightRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_CenterRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_LeftRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_ToolRoot, Type = typeof(Panel))]
    [TemplatePart(Name = KEY_PART_SystemTools, Type = typeof(ItemsControl))]
    [TemplatePart(Name = KEY_PART_Widgets, Type = typeof(ItemsControl))]
    [TemplatePart(Name = KEY_PART_Topics, Type = typeof(ListBox))]
    [TemplatePart(Name = KEY_PART_TaskController, Type = typeof(ToggleButton))]

    [TemplatePart(Name = PART_Bar, Type = typeof(Border))]
    [TemplatePart(Name = PART_SlidingBar, Type = typeof(Border))]
    [TemplatePart(Name = PART_Carousel, Type = typeof(StackPanel))]

    [TemplateVisualState(Name = VSMSTATE_Expanded, GroupName = VSMGROUP_ExpandedStateGroup)]
    [TemplateVisualState(Name = VSMSTATE_Unexpanded, GroupName = VSMGROUP_ExpandedStateGroup)]
    [TemplateVisualState(Name = VSMSTATE_Normal, GroupName = VSMGROUP_NavigationStateGroup)]
    [TemplateVisualState(Name = VSMSTATE_MouseOverLeft, GroupName = VSMGROUP_NavigationStateGroup)]
    [TemplateVisualState(Name = VSMSTATE_MouseOverRight, GroupName = VSMGROUP_NavigationStateGroup)]
    [WidgetMeta(Category = NParams.CategoryCommon, Key = NParams.AutoHideSpan
        , Desc = "自动隐藏触发间隔", DefaultValue = NParams.DEFAULT_AUTO_HIDE_SPAN)]
    [WidgetMeta(Category = NParams.CategoryLayout, Key = NParams.ShowInTile
        , Desc = "是否在磁贴中显示", DefaultValue = true)]
    public class Metrobar : Control, IToolbarService, INotifyPropertyChanged
    {
        #region 常量定义
        const string KEY_PART_LeftThumb = "PART_LeftThumb";
        const string KEY_PART_RightThumb = "PART_RightThumb";
        const string KEY_PART_ExpandController = "PART_ExpandController";
        const string KEY_PART_Root = "PART_Root";
        const string KEY_PART_ExpandedAll = "PART_ExpandedAll";
        const string KEY_PART_CollapseAll = "PART_CollapseAll";
        const string KEY_PART_CustomRoot = "PART_CustomRoot";
        const string KEY_PART_WidgetArea = "PART_WidgetArea";
        const string KEY_PART_BotomRoot = "PART_BotomRoot";
        const string KEY_PART_RightRoot = "PART_RightRoot";
        const string KEY_PART_CenterRoot = "PART_CenterRoot";
        const string KEY_PART_LeftRoot = "PART_LeftRoot";
        const string KEY_PART_ToolRoot = "PART_ToolRoot";
        const string KEY_PART_SystemTools = "PART_SystemTools";
        const string KEY_PART_Widgets = "PART_Widgets";
        const string KEY_PART_Topics = "PART_Topics";
        const string KEY_PART_TaskController = "PART_TaskController";
        const string KEY_PART_Iconbar = "PART_Iconbar";
        private const string PART_Bar = "Bar";
        private const string PART_SlidingBar = "SlidingBar";
        private const string PART_Carousel = "Carousel";

        const string VSMSTATE_Expanded = "Expanded";
        const string VSMSTATE_Unexpanded = "Unexpanded";
        const string VSMSTATE_Normal = "Normal";
        const string VSMSTATE_MouseOverLeft = "MouseOverLeft";
        const string VSMSTATE_MouseOverRight = "MouseOverRight";
       const string VSMSTATE_StateVisible = "Visible";
       const string VSMSTATE_StateHidden = "Hidden";

        const string VSMGROUP_ExpandedStateGroup = "ExpandedStateGroup";
        const string VSMGROUP_VisualStateGroup = "VisualStateGroup";
        const string VSMGROUP_NavigationStateGroup = "NavigationStateGroup";

        const string PROPERTY_IsExpanded = "IsExpanded";
        const string PROPERTY_IsLocked = "IsLocked";
        const string PROPERTY_IsTaskExplanded = "IsTaskExplanded";
        const string PROPERTY_Tools = "Tools";
        const string PROPERTY_SelectedTopic = "SelectedTopic";
        const string PROPERTY_TopicGroups = "TopicGroups";
        const string PROPERTY_LayoutGroups = "LayoutGroups";
        #endregion //#region 常量定义

        // Animation duration in milliseconds
        private const double SlidingDurationInMilliseconds = 200;

        private Border bar;
        private Border slidingBar;
        private StackPanel carousel;

        // 基础组件定义
        private Border PART_LeftThumb, PART_RightThumb;
        private ToggleButton PART_ExpandController,PART_TaskController;
        private Panel PART_CustomRoot, PART_WidgetArea, PART_BotomRoot,PART_ToolRoot;
        private Panel PART_RightRoot, PART_CenterRoot, PART_LeftRoot;
        private ItemsControl PART_SystemTools, PART_Widgets;
        private ListBox PART_Topics;
        private Button PART_ExpandedAll, PART_CollapseAll;
        //private Iconbar PART_Iconbar;

        #region 公共属性定义
        // 是否第一次加载模板样式
        private bool _isFirstApplyTemplate = true;
        private bool _IsExpanded;
        private bool _IsTaskExpanded;
        private bool _IsLocked;
        private ObservableCollection<Widget> _Tools;
        private ObservableCollection<TopicNavigationItem> _TopicGroups;
        private ObservableCollection<TileGroupObject> _LayoutGroups;
        /// <summary>专题目录缓存区</summary>
        private Dictionary<string, ObservableCollection<TileGroupObject>> CatalogBuffer;
        private TopicNavigationItem _SelectedTopic;
        /// <summary>获取或设置专题栏是否处于展开状态。</summary>
        public bool IsExpanded
        {
            get { return _IsExpanded; }
            set
            {
                if (_IsExpanded != value)
                {
                    _IsExpanded = value;
                    NotifyPropertyChanged(this, PROPERTY_IsExpanded);
                }
            }
        }
        /// <summary>获取或设置专题栏是否处于锁定状态。</summary>
        public bool IsLocked
        {
            get { return _IsLocked; }
            set
            {
                if (_IsLocked != value)
                {
                    _IsLocked = value;
                    NotifyPropertyChanged(this, PROPERTY_IsLocked);
                }
            }
        }
        /// <summary>获取或设置任务栏是否处于展开状态。</summary>
        public bool IsTaskExplanded
        {
            get { return _IsTaskExpanded; }
            set
            {
                if (_IsTaskExpanded != value)
                {
                    _IsTaskExpanded = value;
                    NotifyPropertyChanged(this, PROPERTY_IsTaskExplanded);
                }
            }
        }
        public ObservableCollection<Widget> Tools
        {
            get { return _Tools; }
            set
            {
                if (_Tools != value)
                {
                    _Tools = value;
                    NotifyPropertyChanged(this, PROPERTY_Tools);
                }
            }
        }
        /// <summary>获取或设置当前选中的专题。<para>设置时填充子节点。</para> </summary>
        public TopicNavigationItem SelectedTopic
        {
            get { return _SelectedTopic; }
            set
            {
                if (_SelectedTopic != value)
                {
                    _SelectedTopic = value;
                    InitializeLayout(_SelectedTopic.Desc);
                    NotifyPropertyChanged(this, PROPERTY_SelectedTopic);
                }
            }
        }
        /// <summary>获取或设置专题清单。</summary>
        public ObservableCollection<TopicNavigationItem> TopicGroups
        {
            get { return _TopicGroups; }
            set
            {
                if (_TopicGroups != value)
                {
                    _TopicGroups = value;
                    NotifyPropertyChanged(this, PROPERTY_TopicGroups);
                }
            }
        }
        /// <summary>获取或设置专题布局清单。</summary>
        public ObservableCollection<TileGroupObject> LayoutGroups
        {
            get { return _LayoutGroups; }
            set
            {
                if (_LayoutGroups != value)
                {
                    _LayoutGroups = value;
                    NotifyPropertyChanged(this, PROPERTY_LayoutGroups);
                }
            }
        }
        #endregion //#region 公共属性定义

        public Metrobar()
        {
            this.DefaultStyleKey = typeof(Metrobar);

            CatalogBuffer = new Dictionary<string, ObservableCollection<TileGroupObject>>();
            Tools = new ObservableCollection<Widget>();
            TopicGroups = new ObservableCollection<TopicNavigationItem>();
            LayoutGroups = new ObservableCollection<TileGroupObject>();

            InitializeTool();
            InitializePart();
            IsExpanded = true;

            // 应用状态变更通知：处理任务栏内容实时性。 
            // Minimized为应用最小化后触发，Showed为窗口打开后触发。
            // 两种状态皆影响任务栏内容。
            Q.EventMonitor.Minimized += (sender, eventArgs) => { if( IsTaskExplanded) this.InitializeIconbar();};
            Q.EventMonitor.Showed+= (sender, eventArgs) => { if( IsTaskExplanded) this.InitializeIconbar();};
        }

        #region 关于是否可以显示

        private int ToInt32(string key)
        {
            int value =1;
            Int32.TryParse(key, out value);
            return value;
        }
        private bool CanShowInTile(NavigationBase Navigation)
        {
            return CanDo(Navigation, NParams.ShowInTile);
        }

        private bool CanDo(NavigationBase Navigation, string Attribute)
        {
            if (string.IsNullOrEmpty(Navigation.ParmsExpression))
                return true;
            var match = Regex.Match(Navigation.ParmsExpression, string.Format("{0}=false;", Attribute));
            if (match.Success)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        #endregion //#region 关于是否可以显示

        #region 关于数据初始化处理
        /// <summary>初始化工具清单。</summary>
        private void InitializeTool()
        {
            if (Q.WidgetManager == null || Q.WidgetManager.GetToolDirectories() == null)
                return;
            // 初始化工具栏
            Tools.Clear();
            (from t in Q.WidgetManager.GetToolDirectories() select t)
                .ToList()
                .ForEach(p =>
                {
                    Tools.Add(p);
                });
        }
        /// <summary>初始化组件清单。</summary>
        private void InitializePart()
        {
            if (Q.Config == null || Q.Config.NavigationConfig == null)
                return;
            TopicGroups.Clear();
            Q.Config.NavigationConfig.Parts
                .Where(p => CanShowInTile(p))
                .ToList()
                .ForEach(Contract =>
                {
                    var entity = new TopicNavigationItem()
                    {
                        Desc = Contract
                    };
                    TopicGroups.Add(entity);
                });
            // 设置选中默认项
            if (TopicGroups.Count > 0)
            {
                SelectedTopic = TopicGroups.First();
            }
        }
        /// <summary>初始化布局</summary>
        /// <param name="Navigation"></param>
        private void InitializeLayout(NavigationBase Navigation)
        {
            if (CatalogBuffer.ContainsKey(Navigation.Code))
            {
                LayoutGroups = CatalogBuffer[Navigation.Code];
                return;
            }
            LayoutGroups = new ObservableCollection<TileGroupObject>();
            if (Navigation is NavDirectory && CanShowInTile(Navigation))
            {
                var dir = Navigation as NavDirectory;
                foreach (var v in dir.SubNotes)
                {
                    if (v is NavDirectory && CanShowInTile(v))
                    {
                        var module = v as NavDirectory;
                        // 获取组件库中的全部组件
                        var children = from c in module.SubNotes
                                       where CanShowInTile(c)
                                       select Q.WidgetManager.Widgets
                                        .FirstOrDefault(p => p.Navigation.Code == c.Code 
                                            && p.Navigation.Caption == c.Caption);

                        var entity = new TileGroupObject() { Caption = v.Caption };
                        foreach (var widget in children.ToList())
                        {
                            var navigation = widget.Navigation as NavUISLXap;
                            int rowSpan = 1;
                            if (widget.Configs.ContainsKey(NParams.RowSpan))
                                rowSpan = ToInt32(widget.Configs[NParams.RowSpan]);
                            int columnSpan = 1;
                            if (widget.Configs.ContainsKey(NParams.ColumnSpan))
                                columnSpan = ToInt32(widget.Configs[NParams.ColumnSpan]);
                            if( rowSpan >2) rowSpan =2;
                            entity.Children.Add(new TileObject
                            {
                                Navigation = widget,
                                Caption = navigation.Caption,
                                Image = navigation.ImageUrl1,
                                ColumnSpan = columnSpan,
                                RowSpan = rowSpan
                            });
                        }
                        LayoutGroups.Add(entity);
                    }
                    else
                    {
                        continue;
                    }
                }
                CatalogBuffer.Add(Navigation.Code, LayoutGroups);
            }
        }
        #endregion //#region 关于数据初始化处理

        DispatcherTimer dispatcherTimer =
            new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };

        private Dictionary<UIElement, ToolbarLayoutDirection> buffer
            = new Dictionary<UIElement, ToolbarLayoutDirection>();

        int r = 0;
        DispatcherTimer timerForWaitToHide;
        public void WaitToHide()
        {
            if (timerForWaitToHide == null)
            {
                timerForWaitToHide = new DispatcherTimer();
                string spanValueString = this.GetConfigValue(NParams.AutoHideSpan);
                double spanValueDouble = -1;
                if (double.TryParse(spanValueString, out spanValueDouble) == false)
                    spanValueDouble = NParams.DEFAULT_AUTO_HIDE_SPAN;
                timerForWaitToHide.Interval = TimeSpan.FromMilliseconds(spanValueDouble);
                timerForWaitToHide.Tick += delegate(object s, EventArgs a)
                {
                    timerForWaitToHide.Stop();
                    this.Collpase();
                };
            }
            timerForWaitToHide.Start();
        }
        public void StopToHide()
        {
            if (timerForWaitToHide != null)
                timerForWaitToHide.Stop();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.DataContext = this;
            this.PART_LeftThumb = base.GetTemplateChild(KEY_PART_LeftThumb) as Border;
            this.PART_RightThumb = base.GetTemplateChild(KEY_PART_RightThumb) as Border;
            this.PART_ExpandController = base.GetTemplateChild(KEY_PART_ExpandController) as ToggleButton;
            this.PART_TaskController = base.GetTemplateChild(KEY_PART_TaskController) as ToggleButton;
            this.PART_CustomRoot = base.GetTemplateChild(KEY_PART_CustomRoot) as Panel;
            this.PART_WidgetArea = base.GetTemplateChild(KEY_PART_WidgetArea) as Panel;
            this.PART_BotomRoot = base.GetTemplateChild(KEY_PART_BotomRoot) as Panel;
            this.PART_ToolRoot = base.GetTemplateChild(KEY_PART_ToolRoot) as Panel;
            this.PART_RightRoot = base.GetTemplateChild(KEY_PART_RightRoot) as Panel;
            this.PART_CenterRoot = base.GetTemplateChild(KEY_PART_CenterRoot) as Panel;
            this.PART_LeftRoot = base.GetTemplateChild(KEY_PART_LeftRoot) as Panel;

            this.PART_SystemTools = base.GetTemplateChild(KEY_PART_SystemTools) as ItemsControl;
            this.PART_Widgets = base.GetTemplateChild(KEY_PART_Widgets) as ItemsControl;
            this.PART_Topics = base.GetTemplateChild(KEY_PART_Topics) as ListBox;
            this.PART_CollapseAll = base.GetTemplateChild(KEY_PART_CollapseAll) as Button;
            this.PART_ExpandedAll = base.GetTemplateChild(KEY_PART_ExpandedAll) as Button;

            bar = GetTemplateChild(PART_Bar) as Border;
            slidingBar = GetTemplateChild(PART_SlidingBar) as Border;
            carousel = GetTemplateChild(PART_Carousel) as StackPanel;

            bar.MouseMove += new MouseEventHandler(Bar_MouseMove);

            #region 处理 PART_LeftThumb
            if (this.PART_LeftThumb != null)
            {
                this.PART_LeftThumb.MouseEnter += (s, e) =>
                {
                    dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
                    r = -1;
                    dispatcherTimer.Start();
                    VisualStateManager.GoToState(this, VSMSTATE_MouseOverLeft, true);
                };
                this.PART_LeftThumb.MouseLeave += (s, e) =>
                {
                    dispatcherTimer.Stop();
                    dispatcherTimer.Tick -= dispatcherTimer_Tick;
                    VisualStateManager.GoToState(this, VSMSTATE_Normal, true);
                };
            }
            #endregion //#region 处理 PART_LeftThumb

            #region 处理 PART_RightThumb
            if (this.PART_RightThumb != null)
            {
                this.PART_RightThumb.MouseEnter += (s, e) =>
                {
                    dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
                    r = 1;
                    dispatcherTimer.Start();
                    VisualStateManager.GoToState(this, VSMSTATE_MouseOverRight, true);
                };
                this.PART_RightThumb.MouseLeave += (s, e) =>
                {
                    dispatcherTimer.Stop();
                    dispatcherTimer.Tick -= dispatcherTimer_Tick;
                    VisualStateManager.GoToState(this, VSMSTATE_Normal, true);
                };
            }
            #endregion //#region 处理 PART_RightThumb

            #region 处理 PART_ExpandController
            if (this.PART_ExpandController != null)
            {
                PART_ExpandController.SetBinding(ToggleButton.IsCheckedProperty
                    , new Binding() { Mode = BindingMode.TwoWay, Path = new PropertyPath(PROPERTY_IsLocked) });
            }
            #endregion //#region 处理 PART_ExpandController

            #region 处理 PART_SystemTools
            if (this.PART_SystemTools != null)
            {
                PART_SystemTools.SetBinding(ItemsControl.ItemsSourceProperty,
                    new Binding("Tools"));
            }
            #endregion //#region 处理 PART_SystemTools

            #region 处理 PART_Widgets
            if (this.PART_Widgets != null)
            {
                PART_Widgets.SetBinding(ItemsControl.ItemsSourceProperty, new Binding(PROPERTY_LayoutGroups));
            }
            #endregion //#region 处理 PART_Widgets

            #region 处理 PART_Topics
            if (this.PART_Topics != null)
            {
                PART_Topics.SetBinding(ListBox.ItemsSourceProperty, new Binding(PROPERTY_TopicGroups));
                PART_Topics.SetBinding(ListBox.SelectedItemProperty
                    , new Binding(PROPERTY_SelectedTopic)
                    {
                        Mode = BindingMode.TwoWay
                    });
            }
            #endregion //#region 处理 PART_Topics

            #region 处理 PART_ToolRoot
            if (this.PART_ToolRoot != null)
            {
                this.PART_ToolRoot.MouseLeave += (s, e) =>
                {
                    if (IsLocked == false) WaitToHide();
                };
                this.PART_ToolRoot.MouseLeftButtonDown += (s, e) =>
                {
                    if (IsExpanded) Expand();
                };
                this.PART_ToolRoot.MouseEnter += (s, e) =>
                {
                    if (IsLocked == false && IsExpanded) this.StopToHide();
                };
            }
            if (this.PART_WidgetArea != null)
            {
                this.PART_WidgetArea.MouseEnter += (s, e) =>
                {
                    if (IsLocked == false && IsExpanded) this.StopToHide();
                };
                
            }
            #endregion //#region 处理 PART_Root

            #region 处理 PART_CollapseAll
            if (this.PART_CollapseAll != null)
            {
                this.PART_CollapseAll.Command = new ActionCommand(this.CollapseAll);
            }
            #endregion //#region 处理 PART_CollapseAll

            #region 处理 PART_ExpandedAll
            if (this.PART_ExpandedAll != null)
            {
                this.PART_ExpandedAll.Command = new ActionCommand(this.ExpandAll);
            }
            #endregion // #region 处理 PART_ExpandedAll

            #region 处理 PART_TaskController
            if (this.PART_TaskController != null)
            {
                PART_TaskController.SetBinding(ToggleButton.IsCheckedProperty
                    , new Binding()
                        {
                            Mode = BindingMode.TwoWay,
                            Path = new PropertyPath(PROPERTY_IsTaskExplanded)
                        });

                PART_TaskController.Checked += (s, e) =>
                {
                    this.ShowIconbar();
                };
                PART_TaskController.Unchecked += (s, e) =>
                {
                    this.HideIconbar();
                };
            }
            #endregion //#region 处理 PART_TaskController

            if (_isFirstApplyTemplate)
            {
                _isFirstApplyTemplate = false;
                this.Collpase();
            }
            foreach (var entry in buffer)
            {
                this.Add(entry.Key,entry.Value);
            }
        }

        void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            if (r > 0)
            {
                PART_Widgets.GetScrollHost().LineRight();
            }
            else if (r < 0)
            {
                PART_Widgets.GetScrollHost().LineLeft();
            }
        }

        #region Taskbar

        private void InitializeIconbar()
        {
            carousel.Children.Clear();
            var items = from widget in Q.WidgetManager.Widgets
                        where widget.PartElement != null
                        && widget.PartElement.WidgetContent != null
                        && widget.PartElement.WidgetContent is WidgetControl
                        &&( widget.PartElement.WidgetContent as WidgetControl).IsMinimized
                        select widget.PartElement.WidgetContent as WidgetControl;
            foreach (var widget in items)
            {
                var icon = new WindowIcon()
                    {
                        Title = widget.Navigation.Caption,
                        Thumbnail = widget.ThumbnailImage,
                        Window = widget.Widget
                    };
                icon.Click += (sender, eventArgs) =>
                {
                    var senderIcon = sender as WindowIcon;

                    if (senderIcon != null && senderIcon.Window != null)
                    {
                        var widgetElement = senderIcon.Window.PartElement.WidgetContent as WidgetControl;
                        widgetElement.OnRestore();
                        this.IsTaskExplanded = false;
                    }
                };
                carousel.Children.Add(icon);
            }
            Canvas.SetLeft(slidingBar, 0);
        }
        private void ShowIconbar()
        {
            InitializeIconbar();
            VisualStateManager.GoToState(this, VSMSTATE_StateVisible, true);
        }
        private void HideIconbar()
        {
            carousel.Children.Clear();
            VisualStateManager.GoToState(this, VSMSTATE_StateHidden, true);
        }
        // 处理任务栏图片滚动效果。
        private void Bar_MouseMove(object sender, MouseEventArgs e)
        {
            WindowIcon icon = (from item in carousel.Children.OfType<WindowIcon>()
                               where item.IsMouseOver || item.IsPressed
                               select item).FirstOrDefault();

            if (icon != null)
            {
                double a = e.GetPosition(bar).X;
                double b = bar.ActualWidth - bar.Padding.Horizontal();
                double c = slidingBar.ActualWidth;

                if (c > b)
                {
                    double width = b - icon.ActualWidth;
                    if (width != 0)
                    {
                        a -= icon.ActualWidth / 2;
                        if (a < 0) a = 0;
                        if (a > width) a = width;

                        double x = (a / width) * (b - c);

                        Storyboard storyboard = slidingBar.AnimateDoubleProperty("(Canvas.Left)"
                            , null, x, SlidingDurationInMilliseconds);

                        // Get absolute mouse position
                        Point mousePosition = e.GetPosition(null);

                        storyboard.Completed += (s, args) =>
                            {
                                // Select an icon on storyboard completion
                                // That is necessary because MouseOver state won't be proceeded correctly
                                SlidingBarStoryboardCompleted(mousePosition);
                            };
                    }
                }
            }
        }

        private void SlidingBarStoryboardCompleted(Point mousePosition)
        {
            var selectedIcon = (from item in VisualTreeHelper
                                    .FindElementsInHostCoordinates(mousePosition, carousel)
                                    .OfType<WindowIcon>()
                                select item).FirstOrDefault();
            foreach (var icon in carousel.Children.OfType<WindowIcon>())
            {
                icon.Selected = (selectedIcon != null && icon == selectedIcon);
            }
        }
        #endregion //#region Taskbar

        #region 关于配置信息处理
        protected Dictionary<string, string> GetConfigs()
        {
            if (this.Tag is Dictionary<string, string>)
            {
                return this.Tag as Dictionary<string, string>;
            }
            else
            {
                return new Dictionary<string, string>();
            }
        }

        protected string GetConfigValue(string key)
        {
            var config = GetConfigs();

            if (config.ContainsKey(key))
                return config[key];
            else
                return string.Empty;
        }
        #endregion //#region 关于配置信息处理

        #region IToolbarService
        /// <summary>展开工具栏</summary>
        public void Expand()
        {
            if (IsLocked == false)
            {
                VisualStateManager.GoToState(this, VSMSTATE_Expanded, true);
            }
        }
        /// <summary>折叠工具栏</summary>
        public void Collpase()
        {
            if (IsLocked == false)
            {
                VisualStateManager.GoToState(this, VSMSTATE_Unexpanded, true);
            }
        }
        /// <summary>展开全部专题模块</summary>
        public void ExpandAll()
        {
            if (LayoutGroups == null) return;
            foreach (var item in LayoutGroups)
            {
                item.IsExpanded = true;
            }
        }
        /// <summary>折叠全部专题模块</summary>
        public void CollapseAll()
        {
            if (LayoutGroups == null) return;
            foreach (var item in LayoutGroups)
            {
                item.IsExpanded = false;
            }
        }
        
        /// <summary>向工具栏栏中添加一个组件。</summary>
        /// <param name="content">要添加的组件。</param>
        /// <param name="direction">组件在容器中的布局方向。</param>
        public void Add(UIElement content, ToolbarLayoutDirection direction = ToolbarLayoutDirection.Top | ToolbarLayoutDirection.Left)
        {
            if (content == null) return;
            switch (direction)
            {
                case ToolbarLayoutDirection.Top | ToolbarLayoutDirection.Left:
                    if (PART_LeftRoot == null)
                        buffer.Add(content,direction);
                    else
                        PART_LeftRoot.Children.Add(content);
                    break;
                case ToolbarLayoutDirection.Right:
                    if (PART_RightRoot == null)
                        buffer.Add(content, direction);
                    else
                        PART_RightRoot.Children.Add(content);
                    break;
                case ToolbarLayoutDirection.Left:
                    break;
                case ToolbarLayoutDirection.Bottom:
                    if (PART_BotomRoot == null)
                        buffer.Add(content, direction);
                    else
                        PART_BotomRoot.Children.Add(content);
                    break;
                case ToolbarLayoutDirection.Center:
                    if (PART_CenterRoot == null)
                        buffer.Add(content, direction);
                    else
                        PART_CenterRoot.Children.Add(content);
                    break;
                case ToolbarLayoutDirection.Custom:
                    if (PART_CustomRoot == null)
                        buffer.Add(content, direction);
                    else
                        PART_CustomRoot.Children.Add(content);
                    break;
            }
        }
        /// <summary>移除一个任务栏中已经存在的组件。</summary>
        /// <param name="content">要移除的组件。</param>
        public void Remove(UIElement content)
        {
            if (content == null) return;

            if (PART_CustomRoot.Children.Contains(content))
                PART_CustomRoot.Children.Remove(content);
            else if (PART_LeftRoot.Children.Contains(content))
                PART_LeftRoot.Children.Remove(content);
            else if (PART_LeftRoot.Children.Contains(content))
                PART_RightRoot.Children.Remove(content);
            else if (PART_RightRoot.Children.Contains(content))
                PART_BotomRoot.Children.Remove(content);
            else if (PART_BotomRoot.Children.Contains(content))
                PART_CustomRoot.Children.Remove(content);
            else if (PART_CenterRoot.Children.Contains(content))
                PART_CenterRoot.Children.Remove(content);
        }

        #endregion //#region IToolbarService

        #region INotifyPropertyChanged
        /// <summary></summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary></summary>
        /// <param name="sender"></param>
        /// <param name="propertyName"></param>
        protected void NotifyPropertyChanged(object sender, String propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
        #endregion //#region INotifyPropertyChanged
    }
}